#include "mainwindow.h"
#include "QDebug"
#include "ui_mainwindow.h"
#include "QDate"
#include <wtsapi32.h>
#include <winuser.h>
#include <QElapsedTimer>
//#pragma comment(dll, "wtsapi32.dll")

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    WTSRegisterSessionNotification((HWND)this->winId(), NOTIFY_FOR_THIS_SESSION);

    //this->usb.setUserUSBDeviceGUID("13EB360B-BC1E-46CB-AC8B-EF3DA47B4062");

    connect(&this->usb, SIGNAL(printErrorInfo(QString)), this, SLOT(printUSBErrorInfo(QString)));
    //connect(&this->usb, &mywinusb::printErrorInfo, this, &MainWindow::printUSBErrorInfo);

    QStringList sl = {"GET_STATUS", "CLEAR_FEATURE", "RFU1", "SET_FEATURE", "RFU2","SET_ADDRESS","GET_DESCRIPTOR", "SET_DESCRIPTOR","GET_CONFIGURATION","SET_CONFIGURATION","GET_INTERFACE","SET_INTERFACE","SYNCH_FRAME"};
    this->ui->comboBox_bRequest->addItems(sl);

    sl.clear();
    sl = QStringList{"DEVICE", "CONFIGURATION", "STRING", "INTERFACE", "ENDPOINT","DEVICE_QUALIFIER","OTHER_SPEED_CONFIGURATION", "INTERFACE_POWER"};
    this->ui->comboBox_wValue->addItems(sl);

    sl.clear();
    sl = QStringList{"LANGID", "MFC", "PRODUCT", "SERIAL", "CONFIG", "INTERFACE", "OS_STRING"};
    this->ui->comboBox_wValue_str->addItems(sl);
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::printUSBErrorInfo(QString s)
{
    this->ui->textBrowser->append(s);
}

bool MainWindow::nativeEventFilter(const QByteArray &eventType, void *message, long *result)
{
    Q_UNUSED(result);
    static int event_cnt = 0;
    QDateTime current_date_time = QDateTime::currentDateTime();

    #define logprint() qDebug() << __FILE__ << "Line@: " << __LINE__  << ":" << event_cnt++ << "Time@: " << current_date_time.toString("yyyy-MM-dd hh:mm::ss.zzz")

    MSG* msg = static_cast<MSG*>(message);

    if (eventType == "windows_generic_MSG" || eventType == "windows_dispatcher_MSG") {

        if (msg->message == WM_POWERBROADCAST) {
            switch (msg->wParam) {
                case PBT_APMSUSPEND:
                    // 处理挂起事件
                    qDebug() << "System is going to suspend.";
                    return true;
                case PBT_APMRESUMESUSPEND:
                    // 处理从挂起恢复的事件
                    qDebug() << "System has resumed from suspend.";
                    return true;
                default:
                qDebug()  << "msg->wParam:" << msg->wParam;
                logprint();
                    break;
            }
        }
        else if (msg->message == WM_WTSSESSION_CHANGE)//判断登录、注销、锁屏等
        {
             switch (msg->wParam)
             {
             case WTS_SESSION_LOCK:
                  qDebug() << "System is going to WTS_SESSION_LOCK.";
                 break;
             case WTS_SESSION_UNLOCK:
                  qDebug() << "System is going to WTS_SESSION_UNLOCK.";
                 break;
             default:
                 logprint();
                 break;
             }
        }
        else if(msg->message == WM_DEVICECHANGE) {

                if(msg->wParam == DBT_DEVICEARRIVAL)
                {
                    qDebug("usb in");
                }
                if(msg->wParam == DBT_DEVICEREMOVECOMPLETE)
                {
                    qDebug("usb out");
                }
        }
        else{
            //logprint();
        }
    }
    return false;
}



void MainWindow::on_pushButton_write_clicked()
{
    if(this->usb.getUSBConnectState() == false)
    {
        bool ok;
        this->usb.setUserUSBDeviceVID_PID(ui->lineEdit_VID->text().toInt(&ok, 16), ui->lineEdit_PID->text().toInt(&ok, 16));
        if(this->usb.setUSBDeviceConnect() == false)
                return;
    }
    QString text = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss");
    UCHAR* ptext = reinterpret_cast<UCHAR*>(text.toUtf8().data());
    this->ui->textBrowser->clear();
    this->ui->textBrowser->setText("Write: " + text);
    for (int var = 0; var < 1; ++var) {
        if(this->usb.PipeID.PipeOutId[var])
        {
            this->usb.WriteToBulkEndpoint( &this->usb.PipeID.PipeOutId[var],  ptext, text.length());
        }
    }
}
void MainWindow::on_pushButton_read_clicked()
{
    if(this->usb.getUSBConnectState() == false)
    {
        bool ok;
        this->usb.setUserUSBDeviceVID_PID(ui->lineEdit_VID->text().toInt(&ok, 16), ui->lineEdit_PID->text().toInt(&ok, 16));
        if(this->usb.setUSBDeviceConnect() == false)
                return;
    }
    this->ui->textBrowser->clear();
    for (int var = 0; var < 1; ++var) {
        if(this->usb.PipeID.PipeInId[var])
        {
            UCHAR Buffer[1024] = {0};
            ULONG NumberOfBytesToRead = 1024;  // 尝试读取1024字节
            ULONG NumberOfBytesRead = 0;  // 用于接收实际读取的字节数
            NumberOfBytesRead = this->usb.ReadFromBulkEndpoint(&this->usb.PipeID.PipeInId[var], Buffer, NumberOfBytesToRead);

            if (NumberOfBytesRead > 0) {
                qDebug() << "Successfully read" << NumberOfBytesRead << "bytes.";
                std::string receivedText(reinterpret_cast<const char*>(Buffer), NumberOfBytesRead);

                // 输出接收到的文本数据
                qDebug() << "Received text:" << receivedText.c_str();
                this->ui->textBrowser->setText("Read: " +  QString(receivedText.c_str()));
                // 打印接收到的数据
//                for (ULONG i = 0; i < NumberOfBytesRead; ++i) {
//                    qDebug() << "Byte" << i << ":" << static_cast<int>(Buffer[i]);
//                }
            }
            else {
                DWORD lastError = GetLastError();
                qDebug() << "Failed to read from pipe" << static_cast<int>(this->usb.PipeID.PipeInId[var]) << "with error code" << lastError;
            }
        }
    }
}

void MainWindow::on_pushButton_sp_test_clicked()
{
    this->ui->textBrowser->clear();
    if(this->usb.getUSBConnectState() == false)
    {
        bool ok;
        this->usb.setUserUSBDeviceVID_PID(ui->lineEdit_VID->text().toInt(&ok, 16), ui->lineEdit_PID->text().toInt(&ok, 16));
        if(this->usb.setUSBDeviceConnect() == false)
                return;
    }
     QString text64 =  "0123456789012345678901234567890123456789012345678901234567890123";
     QString text512 = "01234567890123456789012345678901234567890123456789012345678901230123456789012345678901234567890123456789012345678901234567890123012345678901234567890123456789012345678901234567890123456789012301234567890123456789012345678901234567890123456789012345678901230123456789012345678901234567890123456789012345678901234567890123012345678901234567890123456789012345678901234567890123456789012301234567890123456789012345678901234567890123456789012345678901230123456789012345678901234567890123456789012345678901234567890123";
     QString text1024= "0123456789012345678901234567890123456789012345678901234567890123012345678901234567890123456789012345678901234567890123456789012301234567890123456789012345678901234567890123456789012345678901230123456789012345678901234567890123456789012345678901234567890123012345678901234567890123456789012345678901234567890123456789012301234567890123456789012345678901234567890123456789012345678901230123456789012345678901234567890123456789012345678901234567890123012345678901234567890123456789012345678901234567890123456789012301234567890123456789012345678901234567890123456789012345678901230123456789012345678901234567890123456789012345678901234567890123012345678901234567890123456789012345678901234567890123456789012301234567890123456789012345678901234567890123456789012345678901230123456789012345678901234567890123456789012345678901234567890123012345678901234567890123456789012345678901234567890123456789012301234567890123456789012345678901234567890123456789012345678901230123456789012345678901234567890123456789012345678901234567890123";
     QString text10240="0123456789012345678901234567890123456789012345678901234567890123012345678901234567890123456789012345678901234567890123456789012301234567890123456789012345678901234567890123456789012345678901230123456789012345678901234567890123456789012345678901234567890123012345678901234567890123456789012345678901234567890123456789012301234567890123456789012345678901234567890123456789012345678901230123456789012345678901234567890123456789012345678901234567890123012345678901234567890123456789012345678901234567890123456789012301234567890123456789012345678901234567890123456789012345678901230123456789012345678901234567890123456789012345678901234567890123012345678901234567890123456789012345678901234567890123456789012301234567890123456789012345678901234567890123456789012345678901230123456789012345678901234567890123456789012345678901234567890123012345678901234567890123456789012345678901234567890123456789012301234567890123456789012345678901234567890123456789012345678901230123456789012345678901234567890123456789012345678901234567890123012345678901234567890123456789012345678901234567890123456789012301234567890123456789012345678901234567890123456789012345678901230123456789012345678901234567890123456789012345678901234567890123012345678901234567890123456789012345678901234567890123456789012301234567890123456789012345678901234567890123456789012345678901230123456789012345678901234567890123456789012345678901234567890123012345678901234567890123456789012345678901234567890123456789012301234567890123456789012345678901234567890123456789012345678901230123456789012345678901234567890123456789012345678901234567890123012345678901234567890123456789012345678901234567890123456789012301234567890123456789012345678901234567890123456789012345678901230123456789012345678901234567890123456789012345678901234567890123012345678901234567890123456789012345678901234567890123456789012301234567890123456789012345678901234567890123456789012345678901230123456789012345678901234567890123456789012345678901234567890123012345678901234567890123456789012345678901234567890123456789012301234567890123456789012345678901234567890123456789012345678901230123456789012345678901234567890123456789012345678901234567890123012345678901234567890123456789012345678901234567890123456789012301234567890123456789012345678901234567890123456789012345678901230123456789012345678901234567890123456789012345678901234567890123012345678901234567890123456789012345678901234567890123456789012301234567890123456789012345678901234567890123456789012345678901230123456789012345678901234567890123456789012345678901234567890123012345678901234567890123456789012345678901234567890123456789012301234567890123456789012345678901234567890123456789012345678901230123456789012345678901234567890123456789012345678901234567890123012345678901234567890123456789012345678901234567890123456789012301234567890123456789012345678901234567890123456789012345678901230123456789012345678901234567890123456789012345678901234567890123012345678901234567890123456789012345678901234567890123456789012301234567890123456789012345678901234567890123456789012345678901230123456789012345678901234567890123456789012345678901234567890123012345678901234567890123456789012345678901234567890123456789012301234567890123456789012345678901234567890123456789012345678901230123456789012345678901234567890123456789012345678901234567890123012345678901234567890123456789012345678901234567890123456789012301234567890123456789012345678901234567890123456789012345678901230123456789012345678901234567890123456789012345678901234567890123012345678901234567890123456789012345678901234567890123456789012301234567890123456789012345678901234567890123456789012345678901230123456789012345678901234567890123456789012345678901234567890123012345678901234567890123456789012345678901234567890123456789012301234567890123456789012345678901234567890123456789012345678901230123456789012345678901234567890123456789012345678901234567890123012345678901234567890123456789012345678901234567890123456789012301234567890123456789012345678901234567890123456789012345678901230123456789012345678901234567890123456789012345678901234567890123012345678901234567890123456789012345678901234567890123456789012301234567890123456789012345678901234567890123456789012345678901230123456789012345678901234567890123456789012345678901234567890123012345678901234567890123456789012345678901234567890123456789012301234567890123456789012345678901234567890123456789012345678901230123456789012345678901234567890123456789012345678901234567890123012345678901234567890123456789012345678901234567890123456789012301234567890123456789012345678901234567890123456789012345678901230123456789012345678901234567890123456789012345678901234567890123012345678901234567890123456789012345678901234567890123456789012301234567890123456789012345678901234567890123456789012345678901230123456789012345678901234567890123456789012345678901234567890123012345678901234567890123456789012345678901234567890123456789012301234567890123456789012345678901234567890123456789012345678901230123456789012345678901234567890123456789012345678901234567890123012345678901234567890123456789012345678901234567890123456789012301234567890123456789012345678901234567890123456789012345678901230123456789012345678901234567890123456789012345678901234567890123012345678901234567890123456789012345678901234567890123456789012301234567890123456789012345678901234567890123456789012345678901230123456789012345678901234567890123456789012345678901234567890123012345678901234567890123456789012345678901234567890123456789012301234567890123456789012345678901234567890123456789012345678901230123456789012345678901234567890123456789012345678901234567890123012345678901234567890123456789012345678901234567890123456789012301234567890123456789012345678901234567890123456789012345678901230123456789012345678901234567890123456789012345678901234567890123012345678901234567890123456789012345678901234567890123456789012301234567890123456789012345678901234567890123456789012345678901230123456789012345678901234567890123456789012345678901234567890123012345678901234567890123456789012345678901234567890123456789012301234567890123456789012345678901234567890123456789012345678901230123456789012345678901234567890123456789012345678901234567890123012345678901234567890123456789012345678901234567890123456789012301234567890123456789012345678901234567890123456789012345678901230123456789012345678901234567890123456789012345678901234567890123012345678901234567890123456789012345678901234567890123456789012301234567890123456789012345678901234567890123456789012345678901230123456789012345678901234567890123456789012345678901234567890123012345678901234567890123456789012345678901234567890123456789012301234567890123456789012345678901234567890123456789012345678901230123456789012345678901234567890123456789012345678901234567890123012345678901234567890123456789012345678901234567890123456789012301234567890123456789012345678901234567890123456789012345678901230123456789012345678901234567890123456789012345678901234567890123012345678901234567890123456789012345678901234567890123456789012301234567890123456789012345678901234567890123456789012345678901230123456789012345678901234567890123456789012345678901234567890123012345678901234567890123456789012345678901234567890123456789012301234567890123456789012345678901234567890123456789012345678901230123456789012345678901234567890123456789012345678901234567890123012345678901234567890123456789012345678901234567890123456789012301234567890123456789012345678901234567890123456789012345678901230123456789012345678901234567890123456789012345678901234567890123012345678901234567890123456789012345678901234567890123456789012301234567890123456789012345678901234567890123456789012345678901230123456789012345678901234567890123456789012345678901234567890123012345678901234567890123456789012345678901234567890123456789012301234567890123456789012345678901234567890123456789012345678901230123456789012345678901234567890123456789012345678901234567890123012345678901234567890123456789012345678901234567890123456789012301234567890123456789012345678901234567890123456789012345678901230123456789012345678901234567890123456789012345678901234567890123012345678901234567890123456789012345678901234567890123456789012301234567890123456789012345678901234567890123456789012345678901230123456789012345678901234567890123456789012345678901234567890123012345678901234567890123456789012345678901234567890123456789012301234567890123456789012345678901234567890123456789012345678901230123456789012345678901234567890123456789012345678901234567890123012345678901234567890123456789012345678901234567890123456789012301234567890123456789012345678901234567890123456789012345678901230123456789012345678901234567890123456789012345678901234567890123012345678901234567890123456789012345678901234567890123456789012301234567890123456789012345678901234567890123456789012345678901230123456789012345678901234567890123456789012345678901234567890123012345678901234567890123456789012345678901234567890123456789012301234567890123456789012345678901234567890123456789012345678901230123456789012345678901234567890123456789012345678901234567890123012345678901234567890123456789012345678901234567890123456789012301234567890123456789012345678901234567890123456789012345678901230123456789012345678901234567890123456789012345678901234567890123012345678901234567890123456789012345678901234567890123456789012301234567890123456789012345678901234567890123456789012345678901230123456789012345678901234567890123456789012345678901234567890123012345678901234567890123456789012345678901234567890123456789012301234567890123456789012345678901234567890123456789012345678901230123456789012345678901234567890123456789012345678901234567890123012345678901234567890123456789012345678901234567890123456789012301234567890123456789012345678901234567890123456789012345678901230123456789012345678901234567890123456789012345678901234567890123012345678901234567890123456789012345678901234567890123456789012301234567890123456789012345678901234567890123456789012345678901230123456789012345678901234567890123456789012345678901234567890123012345678901234567890123456789012345678901234567890123456789012301234567890123456789012345678901234567890123456789012345678901230123456789012345678901234567890123456789012345678901234567890123";

     QString text = text10240;
     UCHAR* ptext = reinterpret_cast<UCHAR*>(text.toUtf8().data());

     UCHAR Buffer[1024] = {0};
     ULONG NumberOfBytesToRead = text.length();  // 尝试读取1024字节
     ULONG NumberOfBytesRead = 0;  // 用于接收实际读取的字节数

     QElapsedTimer timer;
     timer.start();

    int var = 0;
    for (; var < ui->lineEdit->text().toInt(); ++var) {
        this->usb.WriteToBulkEndpoint( &this->usb.PipeID.PipeOutId[0],  ptext, text.length());
//        NumberOfBytesRead = this->usb.ReadFromBulkEndpoint(this->usb.hWinUSBHandle, &this->usb.PipeID.PipeInId[0], Buffer, NumberOfBytesToRead);
//        if (NumberOfBytesRead <= 0) {
//            DWORD lastError = GetLastError();
//            qDebug() << "Failed to read from pipe" << static_cast<int>(this->usb.PipeID.PipeInId[0]) << "with error code" << lastError;
//            break;
//        }
    }
    qint64 elapsedTime = timer.elapsed();  // 返回以毫秒为单位的时间
    QString ret = QString("测试完成: 收发字节数:%1 Byte, 耗时: %2 Ms, 速率: %3 KB/s").arg(var*text.length()).arg(elapsedTime).arg((float)((text.length()*var/1024)/(float(((float)elapsedTime/1000.0f)))));
    this->ui->textBrowser->append(ret);
}


void MainWindow::on_pushButton_read_def_clicked()
{
    this->ui->textBrowser->clear();
    if(this->usb.getUSBConnectState() == false)
    {
        bool ok;
        this->usb.setUserUSBDeviceVID_PID(ui->lineEdit_VID->text().toInt(&ok, 16), ui->lineEdit_PID->text().toInt(&ok, 16));
        if(this->usb.setUSBDeviceConnect() == false)
                return;
    }
    this->usb.ReadDatatoDefaultEndpoint();
}

void MainWindow::on_pushButton_write_def_clicked()
{
    this->ui->textBrowser->clear();
    if(this->usb.getUSBConnectState() == false)
    {
        bool ok;
        this->usb.setUserUSBDeviceVID_PID(ui->lineEdit_VID->text().toInt(&ok, 16), ui->lineEdit_PID->text().toInt(&ok, 16));
        if(this->usb.setUSBDeviceConnect() == false)
                return;
    }
    this->usb.SendDatatoDefaultEndpoint();
}

void MainWindow::on_pushButton_clicked()
{
    this->ui->textBrowser->clear();
    if(this->usb.getUSBConnectState() == false)
    {
        bool ok;
        this->usb.setUserUSBDeviceVID_PID(ui->lineEdit_VID->text().toInt(&ok, 16), ui->lineEdit_PID->text().toInt(&ok, 16));
        if(this->usb.setUSBDeviceConnect() == false)
                return;
    }
    bool OK;
    this->usb.SetupPacket.RequestType = this->ui->lineEdit__bmRequest->text().toInt(&OK, 16);
    this->usb.SetupPacket.Request = this->ui->lineEdit__bRequest->text().toInt(&OK, 16);
    this->usb.SetupPacket.Value = this->ui->lineEdit_wValue->text().toInt(&OK, 16);
    this->usb.SetupPacket.Index = this->ui->lineEdit_wIndex->text().toInt(&OK, 16);
    this->usb.SetupPacket.Length = this->ui->lineEdit_wLength->text().toInt(&OK, 16);

    this->usb.GetUserInterfaceConfig();
}

void MainWindow::on_comboBox_activated(int index)
{
    bool OK;
    int dat = this->ui->lineEdit__bmRequest->text().toInt(&OK, 16);
    if(index){
        dat |= 0x80;
    }
    else{
        dat &= ~0x80;
    }
    this->ui->lineEdit__bmRequest->setText("0x" + QString("%1").arg(dat,2,16,QChar('0')).toUpper());
}

void MainWindow::on_comboBox_2_activated(int index)
{

    bool OK;
    int dat = this->ui->lineEdit__bmRequest->text().toInt(&OK, 16);
    dat &= ~0b01100000;
    switch (index) {
    case 0:break;
    case 1:dat |=  0b00100000;break;
    case 2:dat |=  0b01000000;break;
    default:
       return;
    }
    this->ui->lineEdit__bmRequest->setText("0x" + QString("%1").arg(dat,2,16,QChar('0')).toUpper());
}

void MainWindow::on_comboBox_3_activated(int index)
{
    bool OK;
    int dat = this->ui->lineEdit__bmRequest->text().toInt(&OK, 16);
    dat &= ~0b00011111;
    switch (index) {
    case 0:break;
    case 1:dat |=  0b00000001;break;
    case 2:dat |=  0b00000010;break;
    case 3:dat |=  0b00000011;break;
    default:
       return;
    }
    this->ui->lineEdit__bmRequest->setText("0x" + QString("%1").arg(dat,2,16,QChar('0')).toUpper());
}

void MainWindow::on_comboBox_bRequest_activated(int index)
{
    if(index == 6){
        ui->groupBox_desc->show();
    }
    else{
        ui->groupBox_desc->hide();
    }
    this->ui->lineEdit__bRequest->setText("0x" + QString("%1").arg(index,2,16,QChar('0')).toUpper());
}

void MainWindow::on_comboBox_wValue_activated(int index)
{
    if(index == 2){
        this->ui->groupBox_desc_str->show();
    }
    else{
        this->ui->groupBox_desc_str->hide();
    }

    bool OK;
    int dat = this->ui->lineEdit_wValue->text().toInt(&OK, 16);
    dat &= ~0b1111111100000000;
    if(index > 8)
        return;
    dat |= (index+1) << 8;
    this->ui->lineEdit_wValue->setText("0x" + QString("%1").arg(dat, 4, 16,QChar('0')).toUpper());
}

void MainWindow::on_comboBox_wValue_str_activated(int index)
{
    bool OK;
    int dat = this->ui->lineEdit_wValue->text().toInt(&OK, 16);
    dat &= ~0b0000000011111111;
    if(index > 6)
        return;
    if(index == this->ui->comboBox_wValue_str->count()-1)
        index = 0xEE;
    dat |= index;
    this->ui->lineEdit_wValue->setText("0x" + QString("%1").arg(dat, 4, 16,QChar('0')).toUpper());
}
